package methodRef;

import java.beans.Introspector;
import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;
import java.util.function.Function;

/**
 * 〈〉
 *
 * @author coach tam
 * @email 327395128@qq.com
 * @create 2023/10/17
 * @since 1.0.0
 * 〈坚持灵活 灵活坚持〉
 */
public class MethodRefUtils {
    interface SerializableFunction<T, R> extends Function<T, R>, Serializable{

    }

    class User{
        private String name;

        public String getName() {
            return name;
        }
    }
    public static void main(String[] args) {
        String fieldName = MethodRefUtils.getFieldName(User::getName);
        System.out.println(fieldName);
    }

    private static String getFieldName(SerializableFunction<User,String> function) {
        String fieldName = null;
        try {
            // 第1步 获取SerializedLambda
                //继承了Serializable接口，在实例化时会动态添加writeReplace方法实现
            Method method = function.getClass().getDeclaredMethod("writeReplace");
            method.setAccessible(Boolean.TRUE);
                //该方法会执行后会返回SerializedLambda对象
            SerializedLambda serializedLambda = (SerializedLambda) method.invoke(function);
            // 第2步 通过serializedLambda对象就能获取到方法引用对应的方法名
            String implMethodName = serializedLambda.getImplMethodName();

            //  第3步 转成标准的java字段命名
            // Thus "FooBah" becomes "fooBah" and "X" becomes "x", but "URL" stays as "URL".
            fieldName = Introspector.decapitalize(implMethodName.substring(3));
        } catch (Exception e) {
            e.printStackTrace();
        }
       return fieldName;
    }


}
